home *** CD-ROM | disk | FTP | other *** search
- #undef TEST
- #include <stream.h>
- #include <string.h>
- #include "matrix.hxx"
- #include "strings.hxx"
- #include "symclass.hxx"
-
- /*
- -*++ sym_tab::sym_tab(): constructor for a symbol table
- **
- ** (*++ history:
- ** 7 Dec 87 Bruce Eckel Creation date
- ** ++*)
- **
- ** (*++ detailed:
- ** ++*)
- */
-
- sym_tab::sym_tab() {
- for (int i = 0; i < TBLSZ; tb[i++] = 0)
- ;
- };
-
-
-
- /*
- -*++ sym_tab::~sym_tab(): Destructor for a symbol table
- **
- ** (*++ history:
- ** 7 Dec 87 Bruce Eckel Creation date
- ** ++*)
- **
- ** (*++ detailed:
- ** ++*)
- */
-
- sym_tab::~sym_tab() { /* destructor */
- for (int i = 0; i < TBLSZ; i++)
- for (name* n = tb[i]; n; ) {
- name * nxt = n->next;
- delete n->label;
- delete n;
- n = nxt;
- }
- }
-
-
- /*
- -*++ sym_tab::dump(): dump a symbol table to cout
- **
- ** (*++ history:
- ** 7 Dec 87 Bruce Eckel Creation date
- ** ++*)
- **
- ** (*++ detailed:
- ** ++*)
- */
-
- void sym_tab::dump() {
- for (int i = 0; i < TBLSZ; i++)
- for (name* n=tb[i]; n; n=n->next) {
- cout << n->label << ":\n";
- switch (n->type) {
- case INTEGER : cout << "INTEGER : " << n->value.intval << "\n"; break;
- case DOUBLE : cout << "DOUBLE : " << n->value.doubleval << "\n"; break;
- // case MATRIX : cout << "MATRIX :\n" << n->value.matptr << "\n"; break;
- case KEYWORD : cout << "KEYWORD"; break;
- default: cout << "UNKNOWN TYPE";
- }
- }
- }
-
-
- /*
- -*++ sym_tab::look(): look up or insert table names
- **
- ** (*++ history:
- ** 7 Dec 87 Bruce Eckel Creation date
- ** ++*)
- **
- ** (*++ detailed:
- ** ins == 0 means look up name in table, return 0 if name not found,
- ** pointer to name structure containing the string if found
- ** ins != 0 means insert a new name or a new keyword
- ** ins == NEWNAME means insert new name in table
- ** ins == NEWKEYWORD means insert new keyword in table
- ** ++*)
- */
-
- name* sym_tab::look(char* p, int ins = 0) {
-
- int ii = 0;
- char* pp = p;
- while (*pp) ii = ii<<1 ^ *pp++; /* hash function */
- if (ii < 0) ii = -ii;
- ii %= TBLSZ;
-
- for (name* n=tb[ii]; n; n=n->next) /* search */
- if (strcmp(p,n->label) == 0) return n;
-
- if (ins == 0) return (name *)0; /* string not found */
-
- name* nn = new name; /* insert a new name */
- nn->label = new char[strlen(p) + 1];
- strcpy(nn->label,p);
- nn->type = INTEGER; /* defaults to int */
- nn->value.doubleval = 1;
- nn->value.intval = 1;
- nn->next = tb[ii];
- tb[ii] = nn;
- return nn;
- }
-
-
- /*
- -*++ sym_tab::remove(): removes label but leaves links in place
- **
- ** (*++ history:
- ** 7 Dec 87 Bruce Eckel Creation date
- ** ++*)
- **
- ** (*++ detailed: removes label but leaves links in place. look() won't find
- ** the name, so if the user wants to try re-defining the variable, s/he can.
- ** To do this "neatly", the list would have to be doubly-linked.
- ** ++*)
- */
-
- void sym_tab::remove(name * nn)
- {
- *(nn->label) = 0;
- }
-
-
- #ifdef TEST
- main()
- {
- sym_tab table;
- table.keyword("if");
- table.keyword("then");
- table.keyword("else");
- table.insert("pi")->doubleval = 3.14159;
- table.insert("e")->doubleval = 2.71828;
- table.insert("hello");
- table.look("hello")->doubleval = 7.14;
- table.dump();
-
- }
- #endif